\chapter{系统总体设计}
\label{charp:systemDesign}
为了兼顾透明性与隐私性，故将DID文档分割，
对于非私密部分，我们上链存储。即类似公钥信息、
DID标识符、DID有限时间等公开数据的存储
通过智能合约实现。
而对于私密部分由用户自己存储与管理。
这样做也就保证了数据的隐私性与公开透明可验证性。
这里并不建议身份认证提供商存储用户认证时所使用的私密信息，
即用户认证完成并下载完证书以后，
身份认证提供商就可以删除用户的数据。
\section{智能合约}
智能合约部分主要考虑功能实现与
整个系统操作流程中的区块链部分的权限控制。

\subsection{DID 文档}
由于本文只实现了did这一种方法符号，
故不用考虑DID文档的统一资源定位符为非did的情况，
此时所有操作的默认统一资源定位符为did。
仅通过DID Method和DID Method下的id标识DID。

而对于DID Method的所有权借鉴了域名系统中的设定及：
每个域名只属于一个特定用户，一但该域名被注册，
该用户就成为这个域名的管理员；
其他用户不能再次注册该域名，也不能注册该域名的子域名。
该域名的子域名的添加修改删除所有权属于域名的管理员，
任何用户需要使用子域名时，都需要向管理员申请。

在我们的例子中，只要该DID Method未被注册，
用户即可以注册该DID Method，
一旦注册完成后，该注册用户即拥有该DID Method的所有权，
成为了该DID Method的管理员。
任何该DID Method下的具体标识符的注册都需要得到
该DID Method管理员的允许，然后由新用户添加附带
管理员签名的did文档或者由管理员直接添加新用户的DID文档。

考虑到数字身份的多样性即每个实体可能有多个数字身份，
如某DID Method的管理员A既有微信身份又有QQ身份可能同时还有在校学生的身份。
这样管理员A在为新用户添加DID文档时需要
指定哪个身份发行的该文档。DID文档就可以串起来
形成签发链。
不同于https中的TLS加密层中的两层链，
这样形成的链是不限制长度的，
智能合约只负责把信任的关系串联起来告知用户信任关系，
把信任与否的权利交给了用户与第三方网络服务提供商。

再举一个实例化的例子，对于域名系统中cqu.edu.cn域名的注册。
在注册DID Method：X时，我们用用户X表示还未注册的用户，
管理员X表示用户X注册完成并成为DID Method：X的管理员。
在用户Y申请成为DID Method：X下的用户时，
由DID Method：X的管理员即管理员X添加该用户的DID文档X:Y，
DID文档X:Y表示用户Y申请成为DID Method：X下成员时使用的DID文档。

首先由用户cn，申请DID Method:cn，申请完成后，
用户cn成为管理员cn也就拥有了DID Method:cn的管理权，
现在用户edu向管理员cn申请：“did:cn:edu”的具体标识符，
由于在我们的例子中只使用了did这一种方法符号故下文将使用did文档：“cn:edu”简化，
管理员cn审批通过后将用户edu的DID文档edu:cn的非私密部分放入区块链中存储
至此，edu用户成为DID Method：cn下的注册用户，
用户edu添加DID Method:cn.edu，
并成为DID Method：cn.edu的管理员即管理员cn.edu，
现在用户cqu向edu申请成为DID Method:cn.edu下的用户
这时管理员edu需要使用申请cn:edu具体标识符时的DID文档cn:edu
为edu添加新文档，这样cqu就成为了DID Method：cn.edu下的用户。
在添加DID文档cn.edu:cqu时指定的身份文档cn:edu就形成了一个
签发链。
故设计DID文档入下：
\begin{figure}[h]
  \centerline{\includegraphics[scale=1]{code_DidStruct.png}}
  \caption{DID 链上结构体}
  \label{code:didStruct}
\end{figure}

% \subsection{选择性披露}
\section{身份认证提供商}
身份提供商主要需要完成对用户注册信息的可公开部分存入区块链，
对于私密部分仅仅进行签名，然后在用户申请完成并下载存储在用户终端后，
身份认证提供商就可以删除用户的数据，数据的所有权即在用户。

在用户填写完申请DID的申请表后，
前端将申请表中的信息传给服务端，
服务端将用户填写的信息存入数据库，
并将该条信息的状态设置为未认证。
在管理员审核该信息并认证完成后，
服务端再将DID文档的可公开部分通过智能合约存入区块链中，
同时修改该条信息的状态为已认证，以备用户下载，
用户在认证通过后即可下载证书，
下载完成后前端程序将用户已下载的信息发送到服务端，
随后服务端销毁存入数据库的私密信息。至此整个认证流程完成。

\section{用户端}
在用户端，我们需要考虑两个问题
\xuhaotype[6]
\xuhao 证书的复用。
\xuhao 证书中信息的选择性披露。
\resetxuhao
即将认证信息选择性披露给第三方网络服务提供商。

举一个实例化的例子，在日常生活中，
在参加双选会时要求是应届毕业生参加，
则在双选会的会场入口会设置学生的年级检查，
而我们的学生证不仅仅认证了我们的年级，
还包含其他属性如：专业，
而我们实在不想将该信息提供给会场入口的工作人员，
但又没有只填写了年级的有效证件，
则我们需要将学生证的专业部分的信息遮挡后给工作人员检查。
而在数字身份的例子中，对于已经颁发的证书，
怎么实现只披露部分信息地复用该证书，而不是重新申请新证书。
我们则通过\ref{sec:Merkle proof}小节中叙述的那样通过
Merkle Tree的选择性披露进行证书的复用。

在复用时为了保证第三方能够验证，需要发送以下信息：
\xuhaotype[6]
\xuhao 用户披露的信息即其在Merkle树的索引位置。
\xuhao Proof数组。
\xuhao 身份认证提供商对Merkle Root的签名。
\resetxuhao
以保证第三方能够验证该签名。

\section{第三方网络服务提供商}
第三方网络服务提供商需要考虑两个方面：
\xuhaotype[6]
\xuhao 验证用户信息正确性，即没有经过恶意用户的篡改。
\xuhao 确保签发链为可信的，即确保证书的签发实体是可信的实体。
\resetxuhao

对于第一点，第三方网络服务提供商需要按照\ref{sec:Merkle proof}
小节中叙述的那样，根据Salt Seed生成每个元素对应的salt，
根据生成的salt序列与用户提供的披露信息在Merkle树中的位置，
找到披露信息对应的salt，将该salt与披露信息执行加盐操作，
将加盐后的结果与Proof数组结合，重建Merkle树，
验证用户提供的Merkle Root的值与
重建的Merkle树的Merkle Root的值是否相同，
相同时再验证签名是否为可信实体签发，签发链是否符合预期。

对于第二点，需要检查身份认证提供商的签发链是否为可信的签发链。
当签发链不可信时，即为用户自己在链上伪造了身份提供商，
并构建了伪造的签发链，验证失败。

此外，传统PKI体系的签发太过简单
特别是对于https来说证书只有两层，
即根证书与颁发的证书，
在数字身份管理中如果沿用两层的证书，
那么证书颁发中心的中心化程度就太高，
并且，任何身份认证商都需要作为根证书被用户信任。
% 另外由于我们的数字身份管理是基于以太坊的，
% 在沿用以太坊验证签名的方法时，
% 返回结果为账户地址，如果要判断当前
% 账户地址是否
这样的系统需要保存大量的根证书，
并且注册新的身份认证中心都需要全网所有用户添加根证书。
这样的做法对于整个数字身份管理系统来说效率太低。
故我们选择基于应用的根证书，即系统不保存根证书，
由每个应用软件决定信任该证书与否。
另外，我们通过数字身份链来签发一个身份。
举一个实例化的例子如下：
如在辅导员在认证一个学生的请假条时，
他会使用辅导员的身份，而不是他在社会上作为一个普通公民的身份，
即他选择辅导员的身份来认证该请假条，
这样身份的认证链就成了
.....=>学校=>辅导员=>请假条。
而采用社会上普通人的身份签发时，身份签发链就成了：
.....=>公民=>请假条。
显然，前者的请假条才是可信的。
在上面的例子中，请假这种经常会出现的事务，如果放在链上，
势必会增大以太坊的压力，不足以支撑整个系统，
故对于请假这种时常发生的事务来说，它并未存储在区块链，
整个事务流程都是链下完成。即对于经常发生的事务来说，
我们允许线下签名且深度为一的签名链。考虑到链下签名的安全性问题，
我们仅允许单层签名链，即仅认可具有链上身份的用户对数据进行签名，
使得整个系统的安全问题可被追踪。

\section{本章小结}
本章是要介绍了整个系统的业务流程，
详细的设计完了基于以太坊的数字身份管理系统。
我们的系统设计实现了链上的多层签名链，
与线下的单层签名链，这样有助于整个系统的安全性与稳定性。
